//
// Created by wuzhe on 2022/4/6.
//

#ifndef _REDIS_H_
#define _REDIS_H_

#include <iostream>
#include <string.h>
#include <string>
#include <stdio.h>

#include <hiredis/hiredis.h>
#include <list>
#include <functional>
#include <hiredis/async.h>
class CallbackData {
public:
    std::function<void(std::string)> f;
    CallbackData(std::function<void(std::string)> f):f(f){}
};
void getCallback(redisAsyncContext *c, void *r, void *data);

class Redis
{
public:

    Redis(){}

    ~Redis()
    {
        this->_connect = NULL;
        this->_reply = NULL;
    }

    bool connect(std::string host, int port)
    {
        this->_connect = redisAsyncConnect(host.c_str(), port);
        if(this->_connect != NULL && this->_connect->err)
        {
            printf("connect error: %s\n", this->_connect->errstr);
            return false;
        }
        return true;
    }

    void get(std::string key, std::function<void(std::string)> f)
    {
        auto *data = new CallbackData(f);
        redisAsyncCommand(this->_connect, getCallback, data, "GET %s", key.c_str());
    }
    std::list<std::string> find(std::string key)
    {
        std::list<std::string> res;
//        this->_reply = (redisReply*)redisCommand(this->_connect, "KEYS %s", key.c_str());
//        for (int k = 0; k < this->_reply->elements; ++k) {
//            redisReply* reply = this->_reply->element[k];
//            res.emplace_back(reply->str);
//        }
//        freeReplyObject(this->_reply);
        return res;
    }

    void set(std::string key, std::string value)
    {
        redisAsyncCommand(this->_connect, nullptr, nullptr, "SET %s %s", key.c_str(), value.c_str());
    }
    void del(std::string key)
    {
        redisAsyncCommand(this->_connect, nullptr, nullptr,  "DEL %s", key.c_str());
    }

private:

    redisAsyncContext* _connect;
    redisReply * _reply;

};

#endif  //_REDIS_H_